#pragma once
#include "common.hpp"
#include "socket.hpp"
#include <sys/wait.h>
#include <memory>
#include <functional>

using func_t = std::function<void(std::shared_ptr<Socket> fd, InetAddr &client)>;
class TcpServer
{
public:
    TcpServer() {}
    TcpServer(int port, func_t func) : _socket(std::make_unique<TcpSocket>()), _func(func)
    {
        _socket->CreateTcpServerSocket(port);
    }
    void Start()
    {
        while (true)
        {
            InetAddr peer;
            auto fd = _socket->AcceptOrDie(&peer);
            if (fd == nullptr)
            {
                exit(ACCEPT_ERR);
            }
            // 通信
            int id = fork();
            if (id < 0)
            {
                LOG(Level::FATAL) << "fork error";
                exit(FORK_ERR);
            }
            else if (id == 0)
            {
                _socket->Close();
                if (fork() > 0)
                    exit(OK);
                _func(fd, peer);
            }
            else
            {
                // 父进程
                fd->Close();
                waitpid(id, nullptr, 0);
            }
        }
    }

private:
    std::unique_ptr<Socket> _socket;
    func_t _func;
};